package hashtable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;

/**
 * @author "随风Coding"
 * @email 1431471764@qq.com
 * @date 2025/8/15 09:51
 */
public class CommentElements {

    /**
     * 使用 HashSet 计算两个数组的交集（去重）
     *
     * @param num1 数组1
     * @param num2 数组2
     * @return 交集数组（无序、去重）
     */
    public static int[] completedBySet(int[] num1, int[] num2) {
        HashSet<Integer> hashSet = new HashSet<>();
        HashSet<Integer> resSet = new HashSet<>();

        // 将 num1 元素存入 hashSet（自动去重）
        for (int i : num1) {
            hashSet.add(i);
        }

        // 遍历 num2，筛选出在 hashSet 中存在的元素（自动去重）
        for (int i : num2) {
            if (hashSet.contains(i)) {
                resSet.add(i);
            }
        }

        // 将 Set 转换为数组
        return resSet.stream().mapToInt(Integer::intValue).toArray();
    }

    /**
     * 使用数组标记计算两个数组的交集（优化版，仅返回有效元素）
     *
     * @param num1 数组1
     * @param num2 数组2
     * @return 交集数组（仅包含有效元素，无冗余0）
     */
    public static int[] completedByArray(int[] num1, int[] num2) {
        int[] hash = new int[1002];  // 标记 num1 中出现的元素（1 表示存在）
        int[] hash2 = new int[1002]; // 标记 num2 中出现的元素（1 表示存在）
        ArrayList<Integer> resultList = new ArrayList<>(); // 存储交集元素

        // 标记 num1 中的元素（仅处理 0~1001 范围内的元素）
        for (int i : num1) {
            if (i >= 0 && i < 1002) {
                hash[i] = 1;
            }
        }

        // 标记 num2 中的元素（仅处理 0~1001 范围内的元素）
        for (int i : num2) {
            if (i >= 0 && i < 1002) {
                hash2[i] = 1;
            }
        }

        // 收集交集元素（仅添加有效元素）
        for (int i = 0; i < 1002; i++) {
            if (hash[i] == 1 && hash2[i] == 1) {
                resultList.add(i);
            }
        }

        // 将 List 转换为数组
        int[] res = new int[resultList.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = resultList.get(i);
        }
        return res;
    }

    // ------------------------------ 测试方法 ------------------------------
    public static void main(String[] args) {
        // 测试用例 1：无交集
        int[] num1_1 = {1, 2, 3};
        int[] num2_1 = {4, 5, 6};
        int[] res1_set = completedBySet(num1_1, num2_1);
        int[] res1_array = completedByArray(num1_1, num2_1);
        System.out.println("测试用例1（无交集）:");
        System.out.println("Set 方法结果：" + Arrays.toString(res1_set));  // 预期：[]
        System.out.println("Array 方法结果：" + Arrays.toString(res1_array));  // 预期：[]

        // 测试用例 2：有交集（无重复）
        int[] num1_2 = {1, 2, 3};
        int[] num2_2 = {2, 3, 4};
        int[] res2_set = completedBySet(num1_2, num2_2);
        int[] res2_array = completedByArray(num1_2, num2_2);
        System.out.println("\n测试用例2（有交集无重复）:");
        System.out.println("Set 方法结果：" + Arrays.toString(res2_set));  // 预期：[2, 3]（顺序可能变化）
        System.out.println("Array 方法结果：" + Arrays.toString(res2_array));  // 预期：[2, 3]（顺序可能变化）

        // 测试用例 3：有交集（含重复元素）
        int[] num1_3 = {2, 2, 3};
        int[] num2_3 = {2, 3, 3};
        int[] res3_set = completedBySet(num1_3, num2_3);
        int[] res3_array = completedByArray(num1_3, num2_3);
        System.out.println("\n测试用例3（含重复元素）:");
        System.out.println("Set 方法结果：" + Arrays.toString(res3_set));  // 预期：[2, 3]
        System.out.println("Array 方法结果：" + Arrays.toString(res3_array));  // 预期：[2, 3]

        // 测试用例 4：包含0的交集
        int[] num1_4 = {0, 1, 2};
        int[] num2_4 = {0, 2, 3};
        int[] res4_set = completedBySet(num1_4, num2_4);
        int[] res4_array = completedByArray(num1_4, num2_4);
        System.out.println("\n测试用例4（包含0）:");
        System.out.println("Set 方法结果：" + Arrays.toString(res4_set));  // 预期：[0, 2]（顺序可能变化）
        System.out.println("Array 方法结果：" + Arrays.toString(res4_array));  // 预期：[0, 2]（顺序可能变化）

        // 测试用例 5：元素边界（1000）
        int[] num1_5 = {1000};
        int[] num2_5 = {1000};
        int[] res5_set = completedBySet(num1_5, num2_5);
        int[] res5_array = completedByArray(num1_5, num2_5);
        System.out.println("\n测试用例5（元素边界1000）:");
        System.out.println("Set 方法结果：" + Arrays.toString(res5_set));  // 预期：[1000]
        System.out.println("Array 方法结果：" + Arrays.toString(res5_array));  // 预期：[1000]
    }
}